package com.aerozhonghuan.archive.service.impl;

import com.aerozhonghuan.archive.dto.DeletionResult;
import com.aerozhonghuan.archive.entity.MigrationConfig;
import com.aerozhonghuan.archive.mapper.ArchiveMigrationConfigMapper;
import com.aerozhonghuan.archive.mapper.ArchiveMapper;
import com.aerozhonghuan.archive.mapper.SourceMapper;
import com.aerozhonghuan.archive.service.DataDeletionService;
import com.aerozhonghuan.archive.service.MailService;
import com.aerozhonghuan.archive.config.DynamicDataSourceHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class DataDeletionServiceImpl implements DataDeletionService {

    private static final Logger logger = LoggerFactory.getLogger(DataDeletionServiceImpl.class);

    private final ArchiveMigrationConfigMapper migrationConfigMapper;
    private final ArchiveMapper archiveMapper;
    private final SourceMapper sourceMapper;
    private final MailService mailService;

    public DataDeletionServiceImpl(ArchiveMigrationConfigMapper migrationConfigMapper,
                                   ArchiveMapper archiveMapper,
                                   SourceMapper sourceMapper,
                                   MailService mailService) {
        this.migrationConfigMapper = migrationConfigMapper;
        this.archiveMapper = archiveMapper;
        this.sourceMapper = sourceMapper;
        this.mailService = mailService;
    }

    /**
     * 删除归档库和源库数据，并发送邮件通知删除结果
     *
     * @param baseDate  基准日期，用于计算删除条件
     * @param batchSize 每批次处理记录数
     * @return 每张表的删除结果列表
     */
    @Override
    public List<DeletionResult> executeDeletion(Date baseDate, int batchSize) {
        List<MigrationConfig> configs = migrationConfigMapper.getAllEnabled();
        List<DeletionResult> deletionResults = new ArrayList<>();

        if (configs == null || configs.isEmpty()) {
            logger.warn("迁移配置为空，跳过数据删除。");
            return deletionResults;
        }

        for (MigrationConfig config : configs) {
            logger.info("开始对配置记录 [source: {}.{} -> archive: {}.{}] 执行数据删除。",
                    config.getSourceDbName(), config.getSourceTableName(),
                    config.getTargetDbName(), config.getTargetTableName());

            try {
                // 删除归档库中满足条件的记录
                long totalDeletedArchive = deleteArchiveData(config, baseDate, batchSize);
                // 删除源库中满足条件的记录
                long totalDeletedSource = deleteSourceData(config, baseDate, batchSize);

                // 记录删除结果：先归档库后源库
                deletionResults.add(new DeletionResult(
                        config.getTargetDbName(),
                        config.getTargetTableName(),
                        totalDeletedArchive
                ));
                deletionResults.add(new DeletionResult(
                        config.getSourceDbName(),
                        config.getSourceTableName(),
                        totalDeletedSource
                ));
                logger.info("配置记录 [source: {}.{} -> archive: {}.{}] 数据删除完成。",
                        config.getSourceDbName(), config.getSourceTableName(),
                        config.getTargetDbName(), config.getTargetTableName());
                mailService.sendEmail("数据删除成功通知", "配置记录 [source: " + config.getSourceDbName() + "." + config.getSourceTableName() +
                        " -> archive: " + config.getTargetDbName() + "." + config.getTargetTableName() +
                        "] 删除数据成功，归档库删除 " + totalDeletedArchive + " 条记录，源库删除 " + totalDeletedSource + " 条记录。");
            } catch (Exception e) {
                logger.error("配置记录 [source: {}.{} -> archive: {}.{}] 删除数据时出错：{}",
                        config.getSourceDbName(), config.getSourceTableName(),
                        config.getTargetDbName(), config.getTargetTableName(), e.getMessage(), e);
                // 发送失败邮件给管理员
                try {
                    mailService.sendEmail("数据删除失败通知", "配置记录 [source: " + config.getSourceDbName() + "." + config.getSourceTableName() +
                            " -> archive: " + config.getTargetDbName() + "." + config.getTargetTableName() +
                            "] 删除数据失败，原因：" + e.getMessage());
                } catch (Exception mailEx) {
                    logger.error("失败通知邮件发送失败", mailEx);
                }
            }
        }
        return deletionResults;
    }

    /**
     * 删除归档库中符合条件的记录
     */
    private long deleteArchiveData(MigrationConfig config, Date baseDate, int batchSize) {
        long totalDeleted = 0;
        // 切换到归档数据源
        DynamicDataSourceHolder.setDynamicDataSourceKey(config.getTargetDatasource());
        List<Long> idList = archiveMapper.fetchIdsForDeletion(
                config.getTargetDbName(),
                config.getTargetTableName(),
                config.getTimeStamp(),
                baseDate,
                config.getDeleteMonth()
        );
        if (idList != null && !idList.isEmpty()) {
            logger.info("归档库 [{}.{}] 共查询到 {} 条待删除记录ID",
                    config.getTargetDbName(), config.getTargetTableName(), idList.size());
            for (int i = 0; i < idList.size(); i += batchSize) {
                int end = Math.min(i + batchSize, idList.size());
                List<Long> subList = idList.subList(i, end);
                DynamicDataSourceHolder.setDynamicDataSourceKey(config.getTargetDatasource());
                int rowsDeleted = archiveMapper.deleteArchiveRecordsByIds(
                        config.getTargetDbName(),
                        config.getTargetTableName(),
                        config.getTimeStamp(),
                        subList
                );
                totalDeleted += rowsDeleted;
                logger.info("归档库 [{}.{}] 批次删除：ID范围 [{} - {}]，删除 {} 条记录",
                        config.getTargetDbName(), config.getTargetTableName(),
                        subList.get(0), subList.get(subList.size() - 1), rowsDeleted);
            }
        } else {
            logger.info("归档库 [{}.{}] 无记录满足删除条件", config.getTargetDbName(), config.getTargetTableName());
        }
        return totalDeleted;
    }

    /**
     * 删除源库中符合条件的记录
     */
    private long deleteSourceData(MigrationConfig config, Date baseDate, int batchSize) {
        long totalDeleted = 0;
        // 切换到源数据源
        DynamicDataSourceHolder.setDynamicDataSourceKey(config.getSourceDatasource());
        List<Long> idList = sourceMapper.fetchIdsForDeletion(
                config.getSourceDbName(),
                config.getSourceTableName(),
                config.getTimeStamp(),
                baseDate,
                config.getDeleteMonth()
        );
        if (idList != null && !idList.isEmpty()) {
            logger.info("源库 [{}.{}] 共查询到 {} 条待删除记录ID",
                    config.getSourceDbName(), config.getSourceTableName(), idList.size());
            for (int i = 0; i < idList.size(); i += batchSize) {
                int end = Math.min(i + batchSize, idList.size());
                List<Long> subList = idList.subList(i, end);
                DynamicDataSourceHolder.setDynamicDataSourceKey(config.getSourceDatasource());
                int rowsDeleted = sourceMapper.deleteSourceRecordsByIds(
                        config.getSourceDbName(),
                        config.getSourceTableName(),
                        config.getTimeStamp(),
                        subList
                );
                totalDeleted += rowsDeleted;
                logger.info("源库 [{}.{}] 批次删除：ID范围 [{} - {}]，删除 {} 条记录",
                        config.getSourceDbName(), config.getSourceTableName(),
                        subList.get(0), subList.get(subList.size() - 1), rowsDeleted);
            }
        } else {
            logger.info("源库 [{}.{}] 无记录满足删除条件", config.getSourceDbName(), config.getSourceTableName());
        }
        return totalDeleted;
    }
}
